// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: GPL-3.0-only

package manifest_impl

import (
	"encoding/json"
	"time"

	"gitcode.com/openseaotter/so_proto_gen_go.git/image_api"
)

//application/vnd.oci.image.config.v1+json
//https://github.com/opencontainers/image-spec/blob/main/config.md

type OciImageConfig struct {
	User         string            `json:"User"`
	ExposedPorts map[string]any    `json:"ExposedPorts,omitempty"`
	Env          []string          `json:"Env,omitempty"`
	Entrypoint   []string          `json:"Entrypoint,omitempty"`
	Cmd          []string          `json:"Cmd,omitempty"`
	Volumes      map[string]any    `json:"Volumes,omitempty"`
	WorkingDir   string            `json:"WorkingDir"`
	ArgsEscaped  bool              `json:"ArgsEscaped"`
	StopSignal   string            `json:"StopSignal"`
	Labels       map[string]string `json:"Labels"`
}

type OciImageSpec struct {
	Created      string         `json:"created"`
	Author       string         `json:"author"`
	Architecture string         `json:"architecture"`
	Os           string         `json:"os"`
	Variant      string         `json:"variant"`
	Config       OciImageConfig `json:"config"`
	Rootfs       ImageRootfs    `json:"rootfs"`
	History      []ImageHistory `json:"history,omitempty"`
}

func (oc *OciImageSpec) ToProto() (*image_api.ImageConfig, error) {
	created, err := time.Parse(time.RFC3339Nano, oc.Created)
	if err != nil {
		return nil, err
	}
	exposedPorts := map[string]string{}
	for k, v := range oc.Config.ExposedPorts {
		value, err := json.Marshal(v)
		if err != nil {
			return nil, err
		}
		exposedPorts[k] = string(value)
	}
	volumes := map[string]string{}
	for k, v := range oc.Config.Volumes {
		value, err := json.Marshal(v)
		if err != nil {
			return nil, err
		}
		volumes[k] = string(value)
	}
	return &image_api.ImageConfig{
		Created:      created.UnixMilli(),
		Author:       oc.Author,
		Architecture: oc.Architecture,
		Os:           oc.Os,
		Config: &image_api.ImageConfig_Config{
			User:         oc.Config.User,
			ExposedPorts: exposedPorts,
			Env:          oc.Config.Env,
			Entrypoint:   oc.Config.Entrypoint,
			Cmd:          oc.Config.Cmd,
			Volumes:      volumes,
			WorkingDir:   oc.Config.WorkingDir,
			Labels:       oc.Config.Labels,
		},
	}, nil
}
